package com.yf.exam.modules.user.cert.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;

import com.yf.exam.core.api.ApiRest;
import com.yf.exam.core.api.controller.BaseController;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.user.cert.dto.UserCertDetailDTO;
import com.yf.exam.modules.user.cert.dto.request.UserCertReqDTO;
import com.yf.exam.modules.user.cert.service.UserCertService;
import com.yf.exam.modules.user.cert.service.CertScheduleService;
import com.yf.exam.ability.job.service.JobService;
import com.yf.exam.modules.user.UserUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 用户证书控制器
 */
@Api(tags = "用户证书管理")
@RestController
@RequestMapping("/exam/api/user/cert")
public class UserCertController extends BaseController {

    @Autowired
    private UserCertService userCertService;
    
    @Autowired
    private CertScheduleService certScheduleService;
    
    @Autowired
    private JobService jobService;

    /**
     * 分页查询用户证书详情
     */
    @ApiOperation(value = "分页查询用户证书详情")
    @RequestMapping(value = "/paging", method = RequestMethod.POST)
    public ApiRest<IPage<UserCertDetailDTO>> paging(@RequestBody PagingReqDTO<UserCertReqDTO> reqDTO) {
        // 权限检查和用户ID设置
        validateUserPermission(reqDTO);
        
        IPage<UserCertDetailDTO> page = userCertService.getUserCertDetailPage(reqDTO);
        return super.success(page);
    }

    /**
     * 查询用户证书详情列表
     */
    @ApiOperation(value = "查询用户证书详情列表")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public ApiRest<List<UserCertDetailDTO>> list(@RequestParam(required = false) String userId,
                                                  @RequestParam(required = false) String examId) {
        // 权限检查和用户ID验证
        String validatedUserId = validateAndGetUserId(userId);
        
        List<UserCertDetailDTO> list = userCertService.getUserCertDetailList(validatedUserId, examId);
        return super.success(list);
    }

    /**
     * 手动生成证书（管理员功能）
     */
    @RequiresRoles("sa")
    @ApiOperation(value = "手动生成证书")
    @RequestMapping(value = "/manual", method = RequestMethod.POST)
    public ApiRest manualGenerate(@RequestParam String userId, 
                                 @RequestParam String examId, 
                                 @RequestParam String certId) {
        String certUrl = userCertService.manualGenerateCertificate(userId, examId, certId);
        return super.success(certUrl);
    }



    /**
     * 为考试通过的用户创建证书生成任务（管理员功能）
     */
    @RequiresRoles("sa")
    @ApiOperation(value = "为考试通过的用户创建证书生成任务")
    @RequestMapping(value = "/createTasks/{examId}", method = RequestMethod.POST)
    public ApiRest createCertTasks(@PathVariable String examId) {
        userCertService.generateCertificatesForPassedUsers(examId);
        return super.success();
    }

    /**
     * 删除用户证书
     */
    @ApiOperation(value = "删除用户证书")
    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    public ApiRest deleteUserCertificate(@RequestParam String userId,
                                         @RequestParam String examId,
                                         @RequestParam String certId) {
        // 权限检查：普通用户只能删除自己的证书，管理员可以删除任何用户的证书
        String validatedUserId = validateAndGetUserId(userId);
        
        boolean result = userCertService.deleteUserCertificate(validatedUserId, examId, certId);
        if (result) {
            return super.success("证书删除成功");
        } else {
            return super.failure("证书删除失败，证书可能不存在");
        }
    }

    /**
     * 批量删除指定考试的所有证书（管理员功能）
     */
    @RequiresRoles("sa")
    @ApiOperation(value = "批量删除指定考试的所有证书")
    @RequestMapping(value = "/deleteByExam/{examId}", method = RequestMethod.DELETE)
    public ApiRest deleteAllCertificatesByExam(@PathVariable String examId) {
        int deletedCount = userCertService.deleteAllCertificatesByExam(examId);
        return super.success("成功删除 " + deletedCount + " 个证书");
    }
    
    // ==================== 定时任务管理接口 ====================
    
    /**
     * 手动触发证书失败重试任务（管理员功能）
     */
    @RequiresRoles("sa")
    @ApiOperation(value = "手动触发证书失败重试任务")
    @RequestMapping(value = "/schedule/retry", method = RequestMethod.POST)
    public ApiRest triggerRetryTask() {
        try {
            // 创建一个立即执行的重试任务
            jobService.addCronJob(
                com.yf.exam.modules.user.cert.job.CertRetryJob.class,
                "MANUAL_RETRY_" + System.currentTimeMillis(),
                "手动触发的证书失败重试任务"
            );
            return super.success("证书失败重试任务已触发");
        } catch (Exception e) {
            return super.failure("触发失败重试任务失败：" + e.getMessage());
        }
    }
    

    
    /**
     * 手动触发证书资源清理任务（管理员功能）
     */
    @RequiresRoles("sa")
    @ApiOperation(value = "手动触发证书资源清理任务")
    @RequestMapping(value = "/schedule/cleanup", method = RequestMethod.POST)
    public ApiRest triggerCleanupTask() {
        try {
            // 创建一个立即执行的清理任务
            jobService.addCronJob(
                com.yf.exam.modules.user.cert.job.CertCleanupJob.class,
                "MANUAL_CLEANUP_" + System.currentTimeMillis(),
                "手动触发的证书资源清理任务"
            );
            return super.success("证书资源清理任务已触发");
        } catch (Exception e) {
            return super.failure("触发资源清理任务失败：" + e.getMessage());
        }
    }
    
    /**
     * 重新启动失败重试定时任务（管理员功能）
     */
    @RequiresRoles("sa")
    @ApiOperation(value = "重新启动失败重试定时任务")
    @RequestMapping(value = "/schedule/retry/restart", method = RequestMethod.POST)
    public ApiRest restartRetrySchedule(@RequestParam(value = "cron", required = false) String cron) {
        try {
            if (cron != null && !cron.trim().isEmpty()) {
                certScheduleService.startCertRetrySchedule(cron);
            } else {
                certScheduleService.startCertRetrySchedule();
            }
            return super.success("失败重试定时任务已重新启动");
        } catch (Exception e) {
            return super.failure("重新启动失败重试任务失败：" + e.getMessage());
        }
    }
    
    /**
     * 重新启动资源清理定时任务（管理员功能）
     */
    @RequiresRoles("sa")
    @ApiOperation(value = "重新启动资源清理定时任务")
    @RequestMapping(value = "/schedule/cleanup/restart", method = RequestMethod.POST)
    public ApiRest restartCleanupSchedule(@RequestParam(value = "cron", required = false) String cron) {
        try {
            if (cron != null && !cron.trim().isEmpty()) {
                certScheduleService.startCertCleanupSchedule(cron);
            } else {
                certScheduleService.startCertCleanupSchedule();
            }
            return super.success("资源清理定时任务已重新启动");
        } catch (Exception e) {
            return super.failure("重新启动资源清理任务失败：" + e.getMessage());
        }
    }
    
    // ==================== 私有辅助方法 ====================
    
    /**
     * 验证用户权限并获取有效的用户ID
     */
    private String validateAndGetUserId(String requestUserId) {
        String currentUserId = UserUtils.getUserId();
        return UserUtils.isAdmin(false) ? requestUserId : currentUserId;
    }
    
    /**
     * 验证用户权限并设置查询参数
     */
    private void validateUserPermission(PagingReqDTO<UserCertReqDTO> reqDTO) {
        String currentUserId = UserUtils.getUserId();
        
        // 如果不是管理员，只能查看自己的证书
        if (!UserUtils.isAdmin(false)) {
            if (reqDTO.getParams() == null) {
                reqDTO.setParams(new UserCertReqDTO());
            }
            reqDTO.getParams().setUserId(currentUserId);
        }
    }
}